﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Microsoft.SharePoint;
using Slam.Internal;

namespace Slam
{
	/// <summary>
	/// Provides a wrapper for a Dependency Injection framework.
	/// </summary>
	public static class ComponentService
	{
		private static IComponentFactory _componentFactory;
		private static string _defaultFactoryQualifiedTypeName = "Slam.StructureMap.ComponentFactory, Slam.StructureMap, Version=2.1.0.0, Culture=neutral, PublicKeyToken=ba006d3bc480a2e8";

		/// <summary>
		/// Instantiates a DI framework.  By default that framework is StructureMap.
		/// </summary>
		static ComponentService()
		{
			if (ConfigurationManager.AppSettings == null || ConfigurationManager.AppSettings["Slam.ComponentService.ComponentFactoryQualifiedTypeName"] == null)
			{
				_componentFactory = Type.GetType(_defaultFactoryQualifiedTypeName).CreateInstance<IComponentFactory>();
			}
			else
			{
				_componentFactory = Type.GetType(ConfigurationManager.AppSettings["Slam.ComponentService.ComponentFactoryQualifiedTypeName"]).CreateInstance<IComponentFactory>();
			}
		}

		/// <summary>
		/// Resets the underlying IoC container.
		/// </summary>
		public static void ClearInstances()
		{
			_componentFactory.ResetContainer();
		}

		/// <summary>
		/// Gets an instance of the given type T.
		/// </summary>
		/// <typeparam name="T">Type of instance to retrieve</typeparam>
		/// <returns>Instance of given Type</returns>
		public static T GetInstance<T>()
		{   
			return _componentFactory.GetInstance<T>();
		}

		/// <summary>
		/// Gets an instance of the given type T.
		/// </summary>
		/// <typeparam name="T">Type of instance to retrieve</typeparam>
		/// <param name="siteCollection">SiteCollection providing context for correspondence to a SLAM Configuration DataMapping</param>
		/// <param name="site">Site providing context for correspondence to a SLAM configured type </param>
		/// <param name="typeName">A SLAM configured type for which to retrieve a corresponding instance.</param>
		/// <returns>Instance of given Type</returns>
		public static T GetInstance<T>(string siteCollection, string site, string typeName)
		{
			return _componentFactory.GetInstance<T>(siteCollection, site, typeName);
		}

		/// <summary>
		/// Gets an instance of the given type T.
		/// </summary>
		/// <typeparam name="T">Type of instance to retrieve</typeparam>
		/// <param name="siteCollection">SiteCollection providing context for correspondence to a SLAM Configuration DataMapping</param>
		/// <param name="site">Site providing context for correspondence to a SLAM configured type </param>
		/// <param name="id">List ID providing context for correspondence to a SLAM configured type</param>
		/// <param name="typeName">A SLAM configured type for which to retrieve a corresponding instance.</param>
		/// <returns>Instance of given Type</returns>
		public static T GetInstance<T>(string siteCollection, string site, string id, string typeName)
		{
			return _componentFactory.GetInstance<T>(siteCollection, site, id, typeName);
		}
	}
}
